package main

import (
	"fmt"
	"time"
)

func main() {
	// 定义信道，类型为bool
	stop := make(chan bool)

	//启动一个goroutine,循环执行，当接收到bool的值是跳出；否则一直执行
	go func() {
		for {
			select {
			case <-stop:
				fmt.Println("监控退出，停止了...")
				return
			default:
				fmt.Println("goroutine监控中...")
				time.Sleep(2 * time.Second)
			}
		}
	}()
	// main goroutine阻塞10秒
	time.Sleep(10 * time.Second)
	fmt.Println("可以了，通知监控停止")
	// 向信道发送信号，goroutine接收信号去做相应的处理
	stop <- true
	//为了检测监控过是否停止，如果没有监控输出，就表示停止了
	time.Sleep(5 * time.Second)

}

/*
例子中我们定义了一个stop的chan,通知它结束后台的goroutine。实现也非常简单，在后台goroutine中，使用select判断stop是否可以接收到值，如果可以接收到，就表示
可以退出了；如果没有接收到，就会执行default里的监控逻辑，继续监控，直到收到stop的通知。

以上是单个goroutine的场景，如果是多个goroutine，每个goroutine底下又开启了多个goroutine的场景呢？在飞雪无情的博客里关于要使用Context，它是这样说的
chan + select的方式，是比较优雅地结束一个goroutine；不过这种方式也有局限性，如果有很多goroutine咋么办呢? 如果一层层的无尽的goroutine呢？这就非常复杂了，即使
我们定义了chan也很难解决这个问题，因为goroutine的关系链就导致了这种场景非常复杂。
*/
